home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / MacMud / Mud 4.0 / swap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-24  |  6.7 KB  |  249 lines  |  [TEXT/MPS ]

  1. #include <sys/types.h>
  2. #include <types.h>
  3. #include <mac.h>
  4. #include <stdio.h>
  5.  
  6. #include "lint.h"
  7. #include "interpret.h"
  8. #include "object.h"
  9. #include "config.h"
  10. #include "exec.h"
  11. #include "rc.h"
  12.  
  13. /*
  14.  * Swap out programs from objects.
  15.  */
  16.  
  17. int num_swapped;
  18. int total_bytes_swapped;
  19. char file_name[100];
  20.  
  21. FILE *swap_file;        /* The swap file is opened once */
  22.  
  23. int total_num_prog_blocks, total_prog_block_size;
  24.  
  25. extern int d_flag;
  26.  
  27. /*
  28.  * marion - adjust pointers for swap out and later relocate on swap in
  29.  *   program
  30.  *   line_numbers
  31.  *   functions
  32.  *   strings
  33.  *   variable_names
  34.  *   inherit
  35.  *   argument_types
  36.  *   type_start
  37.  */
  38. int
  39. locate_out (prog) struct program *prog; {
  40.     char *p = 0; /* keep cc happy */
  41.  
  42.     if (!prog) return 0;
  43.     if (d_flag > 1) {
  44.     debug_message ("locate_out: %lX %lX %lX %lX %lX %lX %lX %lX\n",
  45.         prog->program, prog->line_numbers, prog->functions,
  46.         prog->strings, prog->variable_names, prog->inherit,
  47.         prog->argument_types, prog->type_start);
  48.     }
  49.     prog->program    = &p[prog->program - (char *)prog];
  50.     prog->line_numbers    = (unsigned short *)
  51.     &p[(char *)prog->line_numbers - (char *)prog];
  52.     prog->functions    = (struct function *)
  53.     &p[(char *)prog->functions - (char *)prog];
  54.     prog->strings    = (char **)
  55.     &p[(char *)prog->strings - (char *)prog];
  56.     prog->variable_names= (struct variable *)
  57.     &p[(char *)prog->variable_names - (char *)prog];
  58.     prog->inherit    = (struct inherit *)
  59.     &p[(char *)prog->inherit - (char *)prog];
  60.     if (prog->type_start) {
  61.     prog->argument_types = (unsigned short *)
  62.         &p[(char *)prog->argument_types - (char *)prog];
  63.     prog->type_start = (unsigned short *)
  64.         &p[(char *)prog->type_start - (char *)prog];
  65.     }
  66.     return 1;
  67. }
  68.  
  69.  
  70. /*
  71.  * marion - relocate pointers after swap in
  72.  *   program
  73.  *   line_numbers
  74.  *   functions
  75.  *   strings
  76.  *   variable_names
  77.  *   inherit
  78.  *   argument_types
  79.  *   type_start
  80.  */
  81. int
  82. locate_in (prog) struct program *prog; {
  83.     char *p = (char *)prog;
  84.  
  85.     if (!prog) return 0;
  86.     prog->program    = &p[prog->program - (char *)0];
  87.     prog->line_numbers    = (unsigned short *)
  88.     &p[(char *)prog->line_numbers - (char *)0];
  89.     prog->functions    = (struct function *)
  90.     &p[(char *)prog->functions - (char *)0];
  91.     prog->strings    = (char **)
  92.     &p[(char *)prog->strings - (char *)0];
  93.     prog->variable_names= (struct variable *)
  94.     &p[(char *)prog->variable_names - (char *)0];
  95.     prog->inherit    = (struct inherit *)
  96.     &p[(char *)prog->inherit - (char *)0];
  97.     if (prog->type_start) {
  98.     prog->argument_types = (unsigned short *)
  99.         &p[(char *)prog->argument_types - (char *)0];
  100.     prog->type_start     = (unsigned short *)
  101.         &p[(char *)prog->type_start - (char *)0];
  102.     }
  103.     if (d_flag > 1) {
  104.     debug_message ("locate_in: %lX %lX %lX %lX %lX %lX %lX\n",
  105.         prog->program, prog->line_numbers, prog->functions,
  106.         prog->strings, prog->variable_names, prog->inherit,
  107.         prog->argument_types, prog->type_start);
  108.     }
  109.     return 1;
  110. }
  111.  
  112. /*
  113.  * Swap out an object. Only the program is swapped, not the 'struct object'.
  114.  *
  115.  * marion - the swap seems to corrupt the function table
  116.  */
  117. int swap(struct object *ob)
  118. {
  119.     if (ob->flags & O_DESTRUCTED)
  120.     return 0;
  121.     if (d_flag > 1) { /* marion */
  122.     debug_message("Swap object %s (ref %d)\n", ob->name, ob->ref);
  123.     }
  124.     if (swap_file == 0) {
  125.         char host[50];
  126.         sprintf(file_name, "%s.001", SWAP_FILE, host);
  127.         swap_file = fopen(file_name, "w+b");
  128.         /* Leave this file pointer open ! */
  129.         if (swap_file == 0)
  130.             return 0;
  131.     }
  132.     if (!ob->prog) {
  133.         fprintf(stderr, "warning:no program in object %s, don't swap it\n",
  134.             ob->name);
  135.         /* It's no good freeing a NULL pointer */
  136.         return 0;
  137.     }
  138.     if ((ob->flags & O_HEART_BEAT) || (ob->flags & O_CLONE)) {
  139.         if (d_flag > 1) {
  140.             debug_message ("  object not swapped - heart beat or cloned.\n");
  141.         }
  142.         return 0;
  143.     }
  144.     if (ob->prog->ref > 1 || ob->interactive) {
  145.     if (d_flag > 1) {
  146.         debug_message ("  object not swapped - inherited or interactive.\n");
  147.     }
  148.     return 0;
  149.     }
  150.     /*
  151.      * Has this object already been swapped, and read in again ?
  152.      * Then it is very easy to swap it out again.
  153.      */
  154.     if (ob->swap_num >= 0) {
  155.     total_bytes_swapped += ob->prog->total_size;
  156.     free_prog(ob->prog, 0);        /* Do not free the strings */
  157.     ob->prog = 0;
  158.     ob->flags |= O_SWAPPED;
  159.     num_swapped++;
  160.     return 1;
  161.     }
  162.     /*
  163.      * marion - it is more efficient to write one item the size of the
  164.      *   program to the file than many items of size one. besides, it's
  165.      *   much more reasonable, as the fwrite only fails for the whole
  166.      *   block and not for a part of it.
  167.      */
  168.     ob->swap_num = ftell(swap_file);
  169.     locate_out (ob->prog); /* relocate the internal pointers */
  170.     if (fwrite((char *)ob->prog, ob->prog->total_size, 1, swap_file) != 1) {
  171.     debug_message("I/O error in swap.\n");
  172.     ob->swap_num = -1;
  173.     return 0;
  174.     }
  175.     total_bytes_swapped += ob->prog->total_size;
  176.     num_swapped++;
  177.     free_prog(ob->prog, 0);    /* Don't free the shared strings */
  178.     ob->prog = 0;
  179.     ob->flags |= O_SWAPPED;
  180.     return 1;
  181. }
  182.  
  183. void load_ob_from_swap(ob)
  184.     struct object *ob;
  185. {
  186.     extern int errno;
  187.     struct program tmp_prog;
  188.  
  189.     if (ob->swap_num == -1)
  190.     fatal("Loading not swapped object.\n");
  191.     if (fseek(swap_file, ob->swap_num, 0) == -1)
  192.     fatal("Couldn't seek the swap file, errno %d, offset %d.\n",
  193.           errno, ob->swap_num);
  194.     if (d_flag > 1) { /* marion */
  195.     debug_message("Unswap object %s (ref %d)\n", ob->name, ob->ref);
  196.     }
  197.     /*
  198.      * The size of the program is unkown, so read first part to
  199.      * find out.
  200.      *
  201.      * marion - again, the read in a block is more efficient
  202.      */
  203.     if (fread((char *)&tmp_prog, sizeof tmp_prog, 1, swap_file) != 1) {
  204.     fatal("Couldn't read the swap file.\n");
  205.     }
  206.     ob->prog = (struct program *)xalloc(tmp_prog.total_size);
  207.     memcpy((char *)ob->prog, (char *)&tmp_prog, sizeof tmp_prog);
  208.     fread((char *)ob->prog + sizeof tmp_prog,
  209.       tmp_prog.total_size - sizeof tmp_prog, 1, swap_file);
  210.     /*
  211.      * to be relocated:
  212.      *   program
  213.      *   line_numbers
  214.      *   functions
  215.      *   strings
  216.      *   variable_names
  217.      *   inherit
  218.      *     argument_types
  219.      *     type_start
  220.      */
  221.     locate_in (ob->prog); /* relocate the internal pointers */
  222.  
  223.     /* The reference count will already be 1 ! */
  224.     ob->flags &= ~O_SWAPPED;
  225.     total_bytes_swapped -= ob->prog->total_size;
  226.     num_swapped--;
  227.     total_prog_block_size += ob->prog->total_size;
  228.     total_num_prog_blocks += 1;
  229.     if (fseek(swap_file, 0L, 2) == -1) { /* marion - seek back for more swap */
  230.     fatal("Couldn't seek end the swap file, errno %d.\n", errno);
  231.     }
  232. }
  233.  
  234. void remove_swap_file(ob)
  235.     struct object *ob;
  236. {
  237.     /* Haven't implemented this yet :-( */
  238. }
  239.  
  240. /*
  241.  * This one is called at shutdown. Remove the swap file.
  242.  */
  243. void unlink_swap_file() {
  244.     if (swap_file == 0)
  245.     return;
  246.     fclose(swap_file);
  247.     unlink(file_name);
  248. }
  249.